#include "datamonitor.h"
#include "ui_datamonitor.h"
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QTimer>
#include <QDateTime>
#include <QMessageBox>
#include <QDebug>

DataMonitor::DataMonitor(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DataMonitor),
    historyModel(nullptr),
    chart(nullptr),
    chartView(nullptr),
    monitorTimer(nullptr),
    alertManager(nullptr),
    currentUserId(-1),
    serialPort(nullptr),
    serialDataTimer(nullptr),
    isSerialConnected(false),
    chartUpdateTimer(nullptr),
    currentSeries(nullptr),
    currentChartDeviceId(-1),
    isChartMonitoring(false)
{
    ui->setupUi(this);

    setupUI();
    setupConnections();
    setupSerialPort();
    loadDeviceList();
    setupHistoryModel();
    setupChart();

    // 初始化图表更新定时器
    chartUpdateTimer = new QTimer(this);
    connect(chartUpdateTimer, &QTimer::timeout, this, &DataMonitor::updateChartWithNewData);

    LogManager::logSystem("数据监控模块", "数据监控模块初始化完成");
}

DataMonitor::~DataMonitor()
{
    if (monitorTimer && monitorTimer->isActive()) {
        monitorTimer->stop();
        LogManager::logSystem("数据监控模块", "停止数据监控定时器");
    }

    if (serialPort && serialPort->isOpen()) {
        serialPort->close();
        LogManager::logSystem("数据监控模块", "关闭串口连接");
    }

    if (serialDataTimer && serialDataTimer->isActive()) {
        serialDataTimer->stop();
    }

    if (chartUpdateTimer && chartUpdateTimer->isActive()) {
        chartUpdateTimer->stop();
    }

    delete ui;
    delete historyModel;
    delete chartView;
    delete chart;
    delete monitorTimer;
    delete serialPort;
    delete serialDataTimer;
    delete chartUpdateTimer;

    LogManager::logSystem("数据监控模块", "数据监控模块销毁");
}

void DataMonitor::setAlertManager(AlertManager *alertManager)
{
    this->alertManager = alertManager;
    LogManager::logSystem("数据监控模块", "告警管理器已设置");
}

void DataMonitor::setCurrentUserId(int userId)
{
    this->currentUserId = userId;
}

void DataMonitor::setupUI()
{
    // 设置表格属性
    ui->tableWidgetData->setColumnCount(2);
    ui->tableWidgetData->setHorizontalHeaderLabels(QStringList() << "数据" << "接收时间");

    // 设置列宽
    ui->tableWidgetData->setColumnWidth(0, 500);  // 数据列宽度设置为500像素
    ui->tableWidgetData->setColumnWidth(1, 200);  // 时间列宽度设置为200像素

    // 或者使用比例分配
    // ui->tableWidgetData->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);  // 数据列自动拉伸
    // ui->tableWidgetData->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);  // 时间列根据内容调整

    // 原有的设置
    ui->tableWidgetData->horizontalHeader()->setStretchLastSection(true);

    // 设置历史数据表格
    ui->tableViewHistory->setSelectionBehavior(QAbstractItemView::SelectRows);
    ui->tableViewHistory->setSelectionMode(QAbstractItemView::SingleSelection);

    // 设置时间选择器为当前时间
    QDateTime currentTime = QDateTime::currentDateTime();
    ui->dateTimeEditStart->setDateTime(currentTime.addDays(-7));
    ui->dateTimeEditEnd->setDateTime(currentTime);

    // 设置数据类型的下拉框
    ui->comboBoxDataTypes->clear();
    ui->comboBoxDataTypes->addItem("温度");
    ui->comboBoxDataTypes->addItem("湿度");
    ui->comboBoxDataTypes->addItem("光照强度");
    ui->comboBoxDataTypes->addItem("CO2");
    ui->comboBoxDataTypes->addItem("压力");

    // 设置串口相关UI
    ui->comboBoxBaudRate->clear();
    ui->comboBoxBaudRate->addItem("9600", QSerialPort::Baud9600);
    ui->comboBoxBaudRate->addItem("19200", QSerialPort::Baud19200);
    ui->comboBoxBaudRate->addItem("38400", QSerialPort::Baud38400);
    ui->comboBoxBaudRate->addItem("115200", QSerialPort::Baud115200);
    ui->comboBoxBaudRate->setCurrentIndex(0);

    ui->btnOpenSerial->setText("打开串口");
    ui->labelSerialStatus->setText("串口状态: 未连接");
    ui->labelSerialStatus->setStyleSheet("color: red;");
}

void DataMonitor::setupConnections()
{
    // 原有连接
    connect(ui->btnStartMonitor, &QPushButton::clicked, this, &DataMonitor::onStartMonitor);
    connect(ui->btnQuery, &QPushButton::clicked, this, &DataMonitor::onQueryHistory);
    connect(ui->btnGenerateChart, &QPushButton::clicked, this, &DataMonitor::onGenerateChart);
    connect(ui->comboBoxDevices, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &DataMonitor::onDeviceSelectionChanged);
    connect(ui->btnRefreshDevices, &QPushButton::clicked, this, &DataMonitor::onRefreshDeviceList);

    // 串口连接
    connect(ui->btnOpenSerial, &QPushButton::clicked, this, &DataMonitor::onOpenSerialPort);
    connect(ui->btnRefreshSerial, &QPushButton::clicked, this, &DataMonitor::refreshSerialPorts);
    connect(ui->comboBoxBaudRate, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &DataMonitor::onBaudRateChanged);
}

void DataMonitor::setupSerialPort()
{
    serialPort = new QSerialPort(this);
    serialDataTimer = new QTimer(this);

    connect(serialPort, &QSerialPort::readyRead, this, &DataMonitor::onSerialDataReceived);
    connect(serialPort, QOverload<QSerialPort::SerialPortError>::of(&QSerialPort::error),
            this, &DataMonitor::onSerialErrorOccurred);
    connect(serialDataTimer, &QTimer::timeout, this, &DataMonitor::onSerialDataReceived);

    refreshSerialPorts();
    LogManager::logSystem("数据监控模块", "串口模块初始化完成");
}

void DataMonitor::refreshSerialPorts()
{
    ui->comboBoxSerialPort->clear();

    QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
    foreach (const QSerialPortInfo &port, ports) {
        QString portInfo = QString("%1 - %2").arg(port.portName()).arg(port.description());
        ui->comboBoxSerialPort->addItem(portInfo, port.portName());
    }

    if (ports.isEmpty()) {
        ui->comboBoxSerialPort->addItem("未检测到串口", "");
        ui->btnOpenSerial->setEnabled(false);
    } else {
        ui->btnOpenSerial->setEnabled(true);
    }

    LogManager::logSystem("数据监控模块",
                         QString("刷新串口列表,发现 %1 个可用串口").arg(ports.count()));
}

void DataMonitor::loadDeviceList()
{
    ui->comboBoxDevices->clear();
    ui->comboBoxVisualDevices->clear();

    ui->comboBoxDevices->addItem("选择设备", -1);
    ui->comboBoxVisualDevices->addItem("选择设备", -1);

    QSqlQuery query;
    query.prepare("SELECT device_id, name FROM devices WHERE status = 'online'");

    if (query.exec()) {
        int deviceCount = 0;
        while (query.next()) {
            int deviceId = query.value(0).toInt();
            QString deviceName = query.value(1).toString();

            ui->comboBoxDevices->addItem(deviceName, deviceId);
            ui->comboBoxVisualDevices->addItem(deviceName, deviceId);
            deviceCount++;
        }

        LogManager::logSystem("数据监控模块",
                             QString("加载设备列表成功,共 %1 个在线设备").arg(deviceCount));
    } else {
        QString error = query.lastError().text();
        QMessageBox::warning(this, "警告", "加载设备列表失败: " + error);
        LogManager::logError("加载设备列表失败: " + error, currentUserId);
    }
}

void DataMonitor::setupHistoryModel()
{
    if (historyModel) {
        delete historyModel;
    }

    historyModel = new QSqlTableModel(this);
    historyModel->setTable("sensor_data");
    historyModel->setEditStrategy(QSqlTableModel::OnManualSubmit);

    historyModel->setHeaderData(historyModel->fieldIndex("data_id"), Qt::Horizontal, "数据ID");
    historyModel->setHeaderData(historyModel->fieldIndex("device_id"), Qt::Horizontal, "设备ID");
    historyModel->setHeaderData(historyModel->fieldIndex("timestamp"), Qt::Horizontal, "时间戳");
    historyModel->setHeaderData(historyModel->fieldIndex("temperature"), Qt::Horizontal, "温度");
    historyModel->setHeaderData(historyModel->fieldIndex("humidity"), Qt::Horizontal, "湿度");
    historyModel->setHeaderData(historyModel->fieldIndex("light"), Qt::Horizontal, "光照强度");
    historyModel->setHeaderData(historyModel->fieldIndex("co2"), Qt::Horizontal, "CO2");
    historyModel->setHeaderData(historyModel->fieldIndex("pressure"), Qt::Horizontal, "压力");

    if (historyModel->select()) {
        ui->tableViewHistory->setModel(historyModel);
        LogManager::logSystem("数据监控模块", "历史数据模型初始化成功");
    } else {
        QString error = historyModel->lastError().text();
        LogManager::logError("历史数据模型初始化失败: " + error, currentUserId);
    }
}

void DataMonitor::setupChart()
{
    chart = new QChart();
    chart->setTitle("传感器数据图表");
    chart->setAnimationOptions(QChart::SeriesAnimations);

    chartView = new QChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);

    QVBoxLayout *layout = new QVBoxLayout(ui->widgetChart);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(chartView);
    ui->widgetChart->setLayout(layout);

    LogManager::logSystem("数据监控模块", "图表组件初始化完成");
}

void DataMonitor::onStartMonitor()
{
    int deviceId = ui->comboBoxDevices->currentData().toInt();
    if (deviceId == -1) {
        QMessageBox::warning(this, "警告", "请选择要监测的设备");
        LogManager::logOperation(currentUserId, "开始监测", "未选择设备", "", "");
        return;
    }

    QString deviceName = ui->comboBoxDevices->currentText();
    LogManager::logOperation(currentUserId, "开始监测",
                            QString("设备: %1 (ID: %2)").arg(deviceName).arg(deviceId),
                            "", "");

    ui->tableWidgetData->setRowCount(0);

    if (!monitorTimer) {
        monitorTimer = new QTimer(this);
        connect(monitorTimer, &QTimer::timeout, this, &DataMonitor::updateRealTimeData);
    }

    monitorTimer->start(2000);
    ui->btnStartMonitor->setText("停止监测");

    ui->btnStartMonitor->disconnect();
    connect(ui->btnStartMonitor, &QPushButton::clicked, this, [this]() {
        LogManager::logOperation(currentUserId, "停止监测", "停止实时数据监测", "", "");

        if (monitorTimer && monitorTimer->isActive()) {
            monitorTimer->stop();
        }
        ui->btnStartMonitor->setText("开始监测");

        ui->btnStartMonitor->disconnect();
        connect(ui->btnStartMonitor, &QPushButton::clicked, this, &DataMonitor::onStartMonitor);
    });

    QMessageBox::information(this, "提示", "已开始监测设备数据");
}

void DataMonitor::updateRealTimeData()
{
    int deviceId = ui->comboBoxDevices->currentData().toInt();
    QString deviceName = ui->comboBoxDevices->currentText();

    QSqlQuery query;
    query.prepare("SELECT temperature, humidity, light, co2, pressure, timestamp FROM sensor_data WHERE device_id = ? ORDER BY timestamp DESC LIMIT 1");
    query.addBindValue(deviceId);

    if (query.exec() && query.next()) {
        double temperature = query.value(0).toDouble();
        double humidity = query.value(1).toDouble();
        double light = query.value(2).toDouble();
        double co2 = query.value(3).toDouble();
        double pressure = query.value(4).toDouble();
        QDateTime timestamp = query.value(5).toDateTime();

        int row = ui->tableWidgetData->rowCount();
        ui->tableWidgetData->insertRow(row);

        QString dataStr = QString("温度: %1°C, 湿度: %2%, 光照: %3lx, CO2: %4ppm, 压力: %5hPa")
                         .arg(temperature, 0, 'f', 1)
                         .arg(humidity, 0, 'f', 1)
                         .arg(light, 0, 'f', 0)
                         .arg(co2, 0, 'f', 0)
                         .arg(pressure, 0, 'f', 1);

        ui->tableWidgetData->setItem(row, 0, new QTableWidgetItem(dataStr));
        ui->tableWidgetData->setItem(row, 1, new QTableWidgetItem(timestamp.toString("yyyy-MM-dd HH:mm:ss")));
        ui->tableWidgetData->scrollToBottom();

        if (alertManager) {
            QVariantMap sensorData;
            sensorData["device_id"] = deviceId;
            sensorData["temperature"] = temperature;
            sensorData["humidity"] = humidity;
            sensorData["light"] = light;
            sensorData["co2"] = co2;
            sensorData["pressure"] = pressure;
            sensorData["timestamp"] = timestamp;

            alertManager->checkAlerts(sensorData);
        }

        static int updateCount = 0;
        updateCount++;
        if (updateCount % 10 == 0) {
            LogManager::logSystem("数据监控",
                                QString("实时采集 | 设备:%1 | 温度:%2°C | 湿度:%3% | 光照:%4lx | CO2:%5ppm | 压力:%6hPa")
                                .arg(deviceName)
                                .arg(temperature, 0, 'f', 1)
                                .arg(humidity, 0, 'f', 1)
                                .arg(light, 0, 'f', 0)
                                .arg(co2, 0, 'f', 0)
                                .arg(pressure, 0, 'f', 1));
        }
    } else {
        QString error = query.lastError().text();
        LogManager::logError(QString("获取实时数据失败 - 设备: %1, 错误: %2")
                           .arg(deviceName).arg(error), currentUserId);
    }
}

void DataMonitor::onQueryHistory()
{
    QDateTime startTime = ui->dateTimeEditStart->dateTime();
    QDateTime endTime = ui->dateTimeEditEnd->dateTime();

    if (startTime > endTime) {
        QMessageBox::warning(this, "警告", "开始时间不能晚于结束时间");
        LogManager::logOperation(currentUserId, "查询历史数据",
                               "时间范围错误: 开始时间晚于结束时间", "", "");
        return;
    }

    LogManager::logOperation(currentUserId, "查询历史数据",
                           QString("时间范围: %1 至 %2")
                           .arg(startTime.toString("yyyy-MM-dd HH:mm:ss"))
                           .arg(endTime.toString("yyyy-MM-dd HH:mm:ss")),
                           "", "");

    QString filter = QString("timestamp >= '%1' AND timestamp <= '%2'")
                    .arg(startTime.toString("yyyy-MM-dd HH:mm:ss"))
                    .arg(endTime.toString("yyyy-MM-dd HH:mm:ss"));

    historyModel->setFilter(filter);

    if (historyModel->select()) {
        ui->tableViewHistory->resizeColumnsToContents();
        int recordCount = historyModel->rowCount();

        QMessageBox::information(this, "查询结果",
                                QString("查询到 %1 条记录").arg(recordCount));

        LogManager::logSystem("数据监控模块",
                            QString("历史数据查询成功,共 %1 条记录").arg(recordCount));
    } else {
        QString error = historyModel->lastError().text();
        QMessageBox::critical(this, "错误", "查询失败: " + error);
        LogManager::logError("历史数据查询失败: " + error, currentUserId);
    }
}

QString DataMonitor::getFieldNameFromDataType(const QString &dataType)
{
    if (dataType == "温度") return "temperature";
    else if (dataType == "湿度") return "humidity";
    else if (dataType == "光照强度") return "light";
    else if (dataType == "CO2") return "co2";
    else if (dataType == "压力") return "pressure";
    return "";
}

void DataMonitor::onGenerateChart()
{
    int deviceId = ui->comboBoxVisualDevices->currentData().toInt();
    if (deviceId == -1) {
        QMessageBox::warning(this, "警告", "请选择设备");
        LogManager::logOperation(currentUserId, "生成图表", "未选择设备", "", "");
        return;
    }

    QString deviceName = ui->comboBoxVisualDevices->currentText();
    QString dataType = ui->comboBoxDataTypes->currentText();

    currentChartDeviceId = deviceId;
    currentChartDataType = dataType;

    LogManager::logOperation(currentUserId, "生成图表",
                           QString("设备: %1, 数据类型: %2").arg(deviceName).arg(dataType),
                           "", "");

    // 清除现有图表内容
    chart->removeAllSeries();
    QList<QAbstractAxis*> axes = chart->axes();
    for (QAbstractAxis* axis : axes) {
        chart->removeAxis(axis);
        delete axis;
    }

    QString fieldName = getFieldNameFromDataType(dataType);
    if (fieldName.isEmpty()) {
        QMessageBox::warning(this, "警告", "无效的数据类型");
        return;
    }

    QSqlQuery query;
    query.prepare(QString("SELECT timestamp, %1 FROM sensor_data WHERE device_id = ? ORDER BY timestamp").arg(fieldName));
    query.addBindValue(deviceId);

    currentSeries = new QLineSeries();
    currentSeries->setName(dataType);

    if (query.exec()) {
        int dataCount = 0;
        double minValue = std::numeric_limits<double>::max();
        double maxValue = std::numeric_limits<double>::lowest();
        qint64 minTime = std::numeric_limits<qint64>::max();
        qint64 maxTime = std::numeric_limits<qint64>::lowest();

        while (query.next()) {
            QDateTime timestamp = query.value(0).toDateTime();
            double value = query.value(1).toDouble();
            qint64 timeMs = timestamp.toMSecsSinceEpoch();

            currentSeries->append(timeMs, value);
            dataCount++;

            if (value < minValue) minValue = value;
            if (value > maxValue) maxValue = value;
            if (timeMs < minTime) minTime = timeMs;
            if (timeMs > maxTime) maxTime = timeMs;

            // 记录最后一条数据的时间
            if (dataCount == 1 || timestamp > lastChartUpdateTime) {
                lastChartUpdateTime = timestamp;
            }
        }

        if (dataCount == 0) {
            QMessageBox::warning(this, "警告", "该设备没有可用数据");
            delete currentSeries;
            currentSeries = nullptr;
            LogManager::logSystem("数据监控模块",
                                QString("生成图表失败 - 设备 %1 没有 %2 数据").arg(deviceName).arg(dataType));
            return;
        }

        chart->addSeries(currentSeries);

        // 创建坐标轴
        QDateTimeAxis *axisX = new QDateTimeAxis();
        axisX->setTitleText("时间");
        axisX->setFormat("MM/dd HH:mm");

        if (minTime != std::numeric_limits<qint64>::max() && maxTime != std::numeric_limits<qint64>::lowest()) {
            axisX->setRange(QDateTime::fromMSecsSinceEpoch(minTime),
                           QDateTime::fromMSecsSinceEpoch(maxTime));
        } else {
            QDateTime now = QDateTime::currentDateTime();
            axisX->setRange(now.addDays(-1), now);
        }

        chart->addAxis(axisX, Qt::AlignBottom);
        currentSeries->attachAxis(axisX);

        QValueAxis *axisY = new QValueAxis();
        axisY->setTitleText(dataType);

        if (minValue != std::numeric_limits<double>::max() && maxValue != std::numeric_limits<double>::lowest()) {
            double yMargin = (maxValue - minValue) * 0.1;
            if (yMargin == 0) yMargin = 1.0;
            axisY->setRange(minValue - yMargin, maxValue + yMargin);
        } else {
            axisY->setRange(0, 100);
        }

        chart->addAxis(axisY, Qt::AlignLeft);
        currentSeries->attachAxis(axisY);

        chart->setTitle(QString("%1 - %2 数据趋势图 (共%3个数据点) [实时监控中]")
                       .arg(deviceName)
                       .arg(dataType)
                       .arg(dataCount));

        chart->setTheme(QChart::ChartThemeLight);
        QPen pen(Qt::blue);
        pen.setWidth(2);
        currentSeries->setPen(pen);

        // 启动实时更新定时器 (每2秒检查一次新数据)
        if (!isChartMonitoring) {
            chartUpdateTimer->start(2000);
            isChartMonitoring = true;
        }

        QMessageBox::information(this, "成功",
                                QString("已生成图表并启动实时监控,共 %1 个数据点").arg(dataCount));

        LogManager::logSystem("数据监控模块",
                            QString("成功生成图表并启动实时监控 - 设备: %1, 数据类型: %2, 数据点: %3")
                            .arg(deviceName).arg(dataType).arg(dataCount));
    } else {
        QString error = query.lastError().text();
        QMessageBox::warning(this, "警告", "生成图表失败: " + error);
        LogManager::logError(QString("生成图表失败 - 设备: %1, 错误: %2")
                           .arg(deviceName).arg(error), currentUserId);
        delete currentSeries;
        currentSeries = nullptr;
    }
}

void DataMonitor::updateChartWithNewData()
{
    if (!currentSeries || currentChartDeviceId == -1 || currentChartDataType.isEmpty()) {
        return;
    }

    QString fieldName = getFieldNameFromDataType(currentChartDataType);
    if (fieldName.isEmpty()) {
        return;
    }

    // 查询最后更新时间之后的新数据
    QSqlQuery query;
    query.prepare(QString("SELECT timestamp, %1 FROM sensor_data WHERE device_id = ? AND timestamp > ? ORDER BY timestamp")
                  .arg(fieldName));
    query.addBindValue(currentChartDeviceId);
    query.addBindValue(lastChartUpdateTime.toString("yyyy-MM-dd HH:mm:ss"));

    if (query.exec()) {
        int newDataCount = 0;
        while (query.next()) {
            QDateTime timestamp = query.value(0).toDateTime();
            double value = query.value(1).toDouble();
            qint64 timeMs = timestamp.toMSecsSinceEpoch();

            // 添加新数据点到图表
            currentSeries->append(timeMs, value);
            newDataCount++;

            // 更新最后更新时间
            if (timestamp > lastChartUpdateTime) {
                lastChartUpdateTime = timestamp;
            }
        }

        if (newDataCount > 0) {
            // 更新X轴范围,显示最新的数据
            QList<QAbstractAxis*> axes = chart->axes(Qt::Horizontal);
            if (!axes.isEmpty()) {
                QDateTimeAxis *axisX = qobject_cast<QDateTimeAxis*>(axes.first());
                if (axisX) {
                    QDateTime now = QDateTime::currentDateTime();
                    QDateTime startTime = now.addSecs(-120); // 最近2分钟（120秒）
                    axisX->setRange(startTime, now);
                    axisX->setFormat("HH:mm:ss");            // 显示到秒
                    axisX->setTickCount(10);                 // 控制刻度密度，避免太密
                }
            }

            // 更新Y轴范围
            QList<QPointF> points = currentSeries->points();
            if (!points.isEmpty()) {
                double minValue = std::numeric_limits<double>::max();
                double maxValue = std::numeric_limits<double>::lowest();

                for (const QPointF &point : points) {
                    if (point.y() < minValue) minValue = point.y();
                    if (point.y() > maxValue) maxValue = point.y();
                }

                QList<QAbstractAxis*> yAxes = chart->axes(Qt::Vertical);
                if (!yAxes.isEmpty()) {
                    QValueAxis *axisY = qobject_cast<QValueAxis*>(yAxes.first());
                    if (axisY) {
                        double yMargin = (maxValue - minValue) * 0.1;
                        if (yMargin == 0) yMargin = 1.0;
                        axisY->setRange(minValue - yMargin, maxValue + yMargin);
                    }
                }
            }

            // 更新图表标题显示数据点数量
            int totalPoints = currentSeries->count();
            QString deviceName = ui->comboBoxVisualDevices->currentText();
            chart->setTitle(QString("%1 - %2 数据趋势图 (共%3个数据点) [实时监控中]")
                           .arg(deviceName)
                           .arg(currentChartDataType)
                           .arg(totalPoints));

            LogManager::logSystem("图表实时更新",
                                QString("添加了 %1 个新数据点,当前共 %2 个数据点")
                                .arg(newDataCount).arg(totalPoints));
        }
    } else {
        QString error = query.lastError().text();
        LogManager::logError(QString("图表更新查询失败: %1").arg(error), currentUserId);
    }
}

void DataMonitor::onStopChartUpdate()
{
    if (chartUpdateTimer && chartUpdateTimer->isActive()) {
        chartUpdateTimer->stop();
        isChartMonitoring = false;

        // 更新图表标题,移除"实时监控中"标记
        if (currentSeries) {
            int totalPoints = currentSeries->count();
            QString deviceName = ui->comboBoxVisualDevices->currentText();
            chart->setTitle(QString("%1 - %2 数据趋势图 (共%3个数据点)")
                           .arg(deviceName)
                           .arg(currentChartDataType)
                           .arg(totalPoints));
        }

        LogManager::logSystem("数据监控模块", "停止图表实时监控");
    }
}

void DataMonitor::appendDataToChart(const QDateTime &timestamp, double value)
{
    if (!currentSeries) {
        return;
    }

    qint64 timeMs = timestamp.toMSecsSinceEpoch();
    currentSeries->append(timeMs, value);

    // 更新最后更新时间
    if (timestamp > lastChartUpdateTime) {
        lastChartUpdateTime = timestamp;
    }

    // 自动调整坐标轴范围
    adjustChartAxes();

    // 更新图表标题显示数据点数量
    updateChartTitle();
}
void DataMonitor::adjustChartAxes()
{
    if (!currentSeries || currentSeries->count() == 0) {
        return;
    }

    // 获取X轴（时间轴）
    QList<QAbstractAxis*> xAxes = chart->axes(Qt::Horizontal);
    if (!xAxes.isEmpty()) {
        QDateTimeAxis *axisX = qobject_cast<QDateTimeAxis*>(xAxes.first());
        if (axisX) {
            // 显示最近的时间窗口（例如最近1小时）
            QDateTime now = QDateTime::currentDateTime();
            QDateTime startTime = now.addSecs(-3600); // 显示最近1小时
            axisX->setRange(startTime, now);
        }
    }

    // 获取Y轴（数值轴）
    QList<QAbstractAxis*> yAxes = chart->axes(Qt::Vertical);
    if (!yAxes.isEmpty()) {
        QValueAxis *axisY = qobject_cast<QValueAxis*>(yAxes.first());
        if (axisY) {
            QList<QPointF> points = currentSeries->points();
            double minValue = std::numeric_limits<double>::max();
            double maxValue = std::numeric_limits<double>::lowest();

            for (const QPointF &point : points) {
                if (point.y() < minValue) minValue = point.y();
                if (point.y() > maxValue) maxValue = point.y();
            }

            double yMargin = (maxValue - minValue) * 0.1;
            if (yMargin == 0) yMargin = 1.0;
            axisY->setRange(minValue - yMargin, maxValue + yMargin);
        }
    }
}
void DataMonitor::updateChartTitle()
{
    if (!currentSeries) {
        return;
    }

    int totalPoints = currentSeries->count();
    QString deviceName = ui->comboBoxVisualDevices->currentText();
    QString status = isChartMonitoring ? "[实时监控中]" : "[已停止]";

    chart->setTitle(QString("%1 - %2 数据趋势图 (共%3个数据点) %4")
                   .arg(deviceName)
                   .arg(currentChartDataType)
                   .arg(totalPoints)
                   .arg(status));
}
void DataMonitor::onDeviceSelectionChanged(int index)
{
    if (index > 0) {
        int deviceId = ui->comboBoxDevices->itemData(index).toInt();
        QString deviceName = ui->comboBoxDevices->currentText();

        LogManager::logOperation(currentUserId, "切换监测设备",
                               QString("切换到设备: %1 (ID: %2)").arg(deviceName).arg(deviceId),
                               "", "");
    }
}

void DataMonitor::onRefreshDeviceList()
{
    LogManager::logOperation(currentUserId, "刷新设备列表",
                           "手动刷新监控设备列表", "", "");

    loadDeviceList();
    LogManager::logSystem("数据监控模块", "手动刷新设备列表完成");
}

// ==================== 串口相关函数实现 ====================

void DataMonitor::onOpenSerialPort()
{
    if (isSerialConnected) {
        // 关闭串口
        serialPort->close();
        serialDataTimer->stop();

        ui->btnOpenSerial->setText("打开串口");
        ui->labelSerialStatus->setText("串口状态: 未连接");
        ui->labelSerialStatus->setStyleSheet("color: red;");
        isSerialConnected = false;

        LogManager::logSystem("数据监控模块", "串口已关闭");
        return;
    }

    QString portName = ui->comboBoxSerialPort->currentData().toString();
    if (portName.isEmpty()) {
        QMessageBox::warning(this, "警告", "请选择有效的串口");
        return;
    }

    int baudRate = ui->comboBoxBaudRate->currentData().toInt();

    serialPort->setPortName(portName);
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);

    if (serialPort->open(QIODevice::ReadWrite)) {
        ui->btnOpenSerial->setText("关闭串口");
        ui->labelSerialStatus->setText("串口状态: 已连接");
        ui->labelSerialStatus->setStyleSheet("color: green;");
        isSerialConnected = true;

        serialDataTimer->start(100);

        LogManager::logSystem("数据监控模块",
                            QString("串口连接成功: %1, 波特率: %2").arg(portName).arg(baudRate));
    } else {
        QMessageBox::critical(this, "错误", "无法打开串口: " + serialPort->errorString());
        LogManager::logError(QString("串口打开失败: %1").arg(serialPort->errorString()));
    }
}

void DataMonitor::onCloseSerialPort()
{
    if (serialPort && serialPort->isOpen()) {
        serialPort->close();
        isSerialConnected = false;
        ui->btnOpenSerial->setText("打开串口");
        ui->labelSerialStatus->setText("串口状态: 未连接");
        ui->labelSerialStatus->setStyleSheet("color: red;");
    }
}

void DataMonitor::onSerialDataReceived()
{
    if (serialPort && serialPort->isOpen()) {
        QByteArray newData = serialPort->readAll();
        // 将新数据追加到缓存
        m_serialBuffer.append(newData);

        // 尝试从缓存中解析完整的数据包
        processSerialBuffer(); // ✅ 调用新的处理函数

        // 可选：将原始接收到的数据输出到界面
        // ui->textEditSerialData->append("[RX]: " + QString::fromUtf8(newData.trimmed()));
    }
}

// datamonitor.cpp (在 parseSerialData 函数附近添加)

void DataMonitor::processSerialBuffer()
{
    // 循环处理缓存，直到找不到完整的 JSON 包
    while (true) {
        // ✅ 寻找 '@{' 开始标记
        int startIndex = m_serialBuffer.indexOf("@{");
        if (startIndex == -1) {
            // 没有起始符号，清空缓存（如果缓存过长，防止内存泄漏）
            if (m_serialBuffer.length() > 2048) {
                m_serialBuffer.clear();
            }
            break;
        }

        // ✅ 从 '@' 之后开始寻找 '}' 结束符
        int jsonStart = startIndex + 1; // 跳过 '@' 符号
        int endIndex = m_serialBuffer.indexOf('}', jsonStart);

        if (endIndex == -1) {
            // 找不到完整的结束符号。
            // 缓存中没有完整的包，等待更多数据

            // ✅ 如果起始符在中间，清除之前的无效数据
            if (startIndex > 0) {
                 m_serialBuffer.remove(0, startIndex);
            }
            break;
        }

        // ✅ 提取一个完整的 JSON 包 (从 '{' 到 '}' )
        // 注意：不包括 '@' 符号
        QByteArray completePacket = m_serialBuffer.mid(jsonStart, endIndex - jsonStart + 1);

        // ✅ 从缓存中删除已提取的完整包及其前面的所有数据
        // 这样可以处理粘连在已解析包之后的数据
        m_serialBuffer.remove(0, endIndex + 1);

        // 尝试解析这个完整的 JSON 包
        parseSerialData(completePacket);
    }
}

void DataMonitor::parseSerialData(const QByteArray &data)
{
    QString dataStr = QString::fromUtf8(data).trimmed();

    // 忽略空数据
    if (dataStr.isEmpty()) {
        return;
    }

    // 显示完整的接收数据包
    ui->textEditSerialData->append(QString("[%1] 完整数据包: %2")
                                  .arg(QDateTime::currentDateTime().toString("HH:mm:ss"))
                                  .arg(dataStr));

    // 尝试解析JSON格式的传感器数据
    if (dataStr.startsWith("{") && dataStr.endsWith("}")) {
        QJsonParseError parseError;
        QJsonDocument doc = QJsonDocument::fromJson(dataStr.toUtf8(), &parseError);

        if (parseError.error == QJsonParseError::NoError && doc.isObject()) {
            QJsonObject jsonObj = doc.object();

            // 检查是否包含错误信息
            if (jsonObj.contains("error")) {
                QString errorMsg = jsonObj["error"].toString();
                ui->textEditSerialData->append(QString("[错误] 设备错误: %1").arg(errorMsg));
                LogManager::logError(QString("设备传感器错误: %1").arg(errorMsg), currentUserId);
                return;
            }

            // ✅ 新格式解析：根据字段名称分配device_id
            // 字段映射规则：
            // temp -> device_id: 1, 字段: temperature
            // humi -> device_id: 2, 字段: humidity
            // light -> device_id: 3, 字段: light
            // co2 -> device_id: 4, 字段: co2
            // pressure -> device_id: 5, 字段: pressure
            // buzzer -> 暂时跳过

            // 处理温度数据 (temp -> temperature)
            if (jsonObj.contains("temp")) {
                QVariantMap sensorData;
                sensorData["device_id"] = 1;
                sensorData["temperature"] = jsonObj["temp"].toDouble();
                sensorData["timestamp"] = QDateTime::currentDateTime();

                saveSerialDataToDatabase(sensorData);

                ui->textEditSerialData->append(QString("[成功] 设备1(温度)数据已保存: %.1f°C")
                                              .arg(sensorData["temperature"].toDouble()));

                LogManager::logSystem("串口数据",
                                    QString("成功解析设备1的温度数据: %.1f°C")
                                    .arg(sensorData["temperature"].toDouble()));
            }

            // 处理湿度数据 (humi -> humidity)
            if (jsonObj.contains("humi")) {
                QVariantMap sensorData;
                sensorData["device_id"] = 2;
                sensorData["humidity"] = jsonObj["humi"].toDouble();
                sensorData["timestamp"] = QDateTime::currentDateTime();

                saveSerialDataToDatabase(sensorData);

                ui->textEditSerialData->append(QString("[成功] 设备2(湿度)数据已保存: %.1f%%")
                                              .arg(sensorData["humidity"].toDouble()));

                LogManager::logSystem("串口数据",
                                    QString("成功解析设备2的湿度数据: %.1f%%")
                                    .arg(sensorData["humidity"].toDouble()));
            }

            // 处理光照数据 (light -> light)
            if (jsonObj.contains("light")) {
                QVariantMap sensorData;
                sensorData["device_id"] = 3;
                sensorData["light"] = jsonObj["light"].toDouble();
                sensorData["timestamp"] = QDateTime::currentDateTime();

                saveSerialDataToDatabase(sensorData);

                ui->textEditSerialData->append(QString("[成功] 设备3(光照)数据已保存: %.0f lx")
                                              .arg(sensorData["light"].toDouble()));

                LogManager::logSystem("串口数据",
                                    QString("成功解析设备3的光照数据: %.0f lx")
                                    .arg(sensorData["light"].toDouble()));
            }

            // 处理CO2数据 (co2 -> co2)
            if (jsonObj.contains("co2")) {
                QVariantMap sensorData;
                sensorData["device_id"] = 4;
                sensorData["co2"] = jsonObj["co2"].toDouble();
                sensorData["timestamp"] = QDateTime::currentDateTime();

                saveSerialDataToDatabase(sensorData);

                ui->textEditSerialData->append(QString("[成功] 设备4(CO2)数据已保存: %.0f ppm")
                                              .arg(sensorData["co2"].toDouble()));

                LogManager::logSystem("串口数据",
                                    QString("成功解析设备4的CO2数据: %.0f ppm")
                                    .arg(sensorData["co2"].toDouble()));
            }

            // 处理气压数据 (pressure -> pressure)
            if (jsonObj.contains("pressure")) {
                QVariantMap sensorData;
                sensorData["device_id"] = 5;
                sensorData["pressure"] = jsonObj["pressure"].toDouble();
                sensorData["timestamp"] = QDateTime::currentDateTime();

                saveSerialDataToDatabase(sensorData);

                ui->textEditSerialData->append(QString("[成功] 设备5(气压)数据已保存: %.1f hPa")
                                              .arg(sensorData["pressure"].toDouble()));

                LogManager::logSystem("串口数据",
                                    QString("成功解析设备5的气压数据: %.1f hPa")
                                    .arg(sensorData["pressure"].toDouble()));
            }

            // ✅ 蜂鸣器数据暂时跳过
            if (jsonObj.contains("buzzer")) {
                int buzzerState = jsonObj["buzzer"].toInt();
                ui->textEditSerialData->append(QString("[信息] 蜂鸣器状态: %1 (暂不处理)")
                                              .arg(buzzerState));
                // 后续可以在这里添加蜂鸣器控制逻辑
            }

        } else {
            ui->textEditSerialData->append(QString("[错误] JSON解析失败: %1").arg(parseError.errorString()));
            LogManager::logError(QString("JSON解析错误: %1, 数据: %2")
                               .arg(parseError.errorString()).arg(dataStr), currentUserId);
        }
    }
    else {
        // 其他格式的数据
        ui->textEditSerialData->append(QString("[信息] %1").arg(dataStr));
    }
}

// ✅ 在 datamonitor.cpp 的 saveSerialDataToDatabase 函数末尾添加以下代码

void DataMonitor::saveSerialDataToDatabase(const QVariantMap &sensorData)
{
    if (!sensorData.contains("device_id")) {
        return;
    }

    int deviceId = sensorData["device_id"].toInt();
    QDateTime timestamp = sensorData["timestamp"].toDateTime();

    QSqlQuery query;
    query.prepare("INSERT INTO sensor_data (device_id, timestamp, temperature, humidity, light, co2, pressure) "
                  "VALUES (?, ?, ?, ?, ?, ?, ?)");

    query.addBindValue(deviceId);
    query.addBindValue(timestamp.toString("yyyy-MM-dd HH:mm:ss"));
    query.addBindValue(sensorData.value("temperature", QVariant()).toDouble());
    query.addBindValue(sensorData.value("humidity", QVariant()).toDouble());
    query.addBindValue(sensorData.value("light", QVariant()).toDouble());
    query.addBindValue(sensorData.value("co2", QVariant()).toDouble());
    query.addBindValue(sensorData.value("pressure", QVariant()).toDouble());

    if (query.exec()) {
        // 更新实时数据表格
        int row = ui->tableWidgetData->rowCount();
        ui->tableWidgetData->insertRow(row);

        QString dataStr = QString("温度: %1°C, 湿度: %2%, 光照: %3lx, CO2: %4ppm, 压力: %5hPa")
                         .arg(sensorData.value("temperature", 0).toDouble(), 0, 'f', 1)
                         .arg(sensorData.value("humidity", 0).toDouble(), 0, 'f', 1)
                         .arg(sensorData.value("light", 0).toDouble(), 0, 'f', 0)
                         .arg(sensorData.value("co2", 0).toDouble(), 0, 'f', 0)
                         .arg(sensorData.value("pressure", 0).toDouble(), 0, 'f', 1);

        ui->tableWidgetData->setItem(row, 0, new QTableWidgetItem(dataStr));
        ui->tableWidgetData->setItem(row, 1, new QTableWidgetItem(timestamp.toString("yyyy-MM-dd HH:mm:ss")));
        ui->tableWidgetData->scrollToBottom();

        // 告警检查
        if (alertManager) {
            alertManager->checkAlerts(sensorData);
        }

        // 图表更新
        if (isChartMonitoring && deviceId == currentChartDeviceId && !currentChartDataType.isEmpty()) {
            QString fieldName = getFieldNameFromDataType(currentChartDataType);
            if (!fieldName.isEmpty() && sensorData.contains(fieldName)) {
                double value = sensorData.value(fieldName).toDouble();
                appendDataToChart(timestamp, value);
                LogManager::logSystem("图表实时更新",
                                    QString("设备 %1 接收到新数据，%2: %3")
                                    .arg(deviceId)
                                    .arg(currentChartDataType)
                                    .arg(value));
            }
        }

        // ✅ 新增：发送数据到设备控制页面更新传感器显示
        emit sensorDataUpdated(sensorData);

        LogManager::logSystem("串口数据", QString("设备 %1 数据保存成功").arg(deviceId));
    } else {
        LogManager::logError(QString("设备 %1 数据保存失败: %2")
                           .arg(deviceId).arg(query.lastError().text()));
    }
}

void DataMonitor::onSerialErrorOccurred(QSerialPort::SerialPortError error)
{
    if (error != QSerialPort::NoError) {
        QString errorMsg = serialPort->errorString();
        ui->textEditSerialData->append(QString("[%1] 错误: %2")
                                      .arg(QDateTime::currentDateTime().toString("HH:mm:ss"))
                                      .arg(errorMsg));

        LogManager::logError(QString("串口错误: %1").arg(errorMsg));

        if (error == QSerialPort::ResourceError) {
            onCloseSerialPort();
            QMessageBox::critical(this, "串口错误", "串口连接已断开: " + errorMsg);
        }
    }
}

void DataMonitor::onBaudRateChanged(int index)
{
    if (isSerialConnected) {
        QMessageBox::information(this, "提示", "波特率更改将在下次连接时生效");
    }
}


//// 处理串口缓冲区的完整数据包
//void DataMonitor::processSerialBuffer()
//{
//    // 查找完整的JSON数据包(以\r\n或\n结尾)
//    int endPos = -1;

//    // 查找换行符
//    if ((endPos = serialDataBuffer.indexOf("\r\n")) != -1) {
//        // 找到了完整的数据包
//        QByteArray completePacket = serialDataBuffer.left(endPos);
//        serialDataBuffer.remove(0, endPos + 2);  // 移除已处理的数据

//        // 解析完整的数据包
//        parseSerialData(completePacket);

//        // 递归处理缓冲区中剩余的完整数据包
//        if (serialDataBuffer.contains("\r\n")) {
//            processSerialBuffer();
//        }
//    } else if ((endPos = serialDataBuffer.indexOf("\n")) != -1) {
//        // 兼容只有\n的情况
//        QByteArray completePacket = serialDataBuffer.left(endPos);
//        serialDataBuffer.remove(0, endPos + 1);

//        parseSerialData(completePacket);

//        if (serialDataBuffer.contains("\n")) {
//            processSerialBuffer();
//        }
//    }

//    // 防止缓冲区无限增长(超过2KB清空)
//    if (serialDataBuffer.size() > 2048) {
//        LogManager::logError("串口缓冲区溢出,已清空", currentUserId);
//        serialDataBuffer.clear();
//    }
//}

void DataMonitor::applyUserPermissions()
{
    // 如果需要根据用户角色设置权限,可以在这里实现
}

// 新增:对外提供的设备控制接口
void DataMonitor::sendDeviceControl(const QString &deviceType, int deviceId,
                                   const QString &action, const QJsonObject &params)
{
    if (!serialPort || !serialPort->isOpen()) {
        qDebug() << "串口未连接,无法发送控制指令";
        ui->textEditSerialData->append("[警告] 串口未连接,无法发送控制指令");
        return;
    }

    QJsonObject command;
    command["device_type"] = deviceType;
    command["device_id"] = deviceId;
    command["action"] = action;
    command["params"] = params;
    command["timestamp"] = QDateTime::currentMSecsSinceEpoch();

    QJsonDocument doc(command);
    QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
    jsonData.prepend('@');          // ✅ 改这里
    jsonData.append("\r\n");        // ✅ 改这里

    qint64 bytesWritten = serialPort->write(jsonData);
    serialPort->flush();
    serialPort->waitForBytesWritten(1000);

    if (bytesWritten == -1) {
        qDebug() << "控制指令发送失败:" << serialPort->errorString();
        ui->textEditSerialData->append(QString("[失败] 控制指令发送失败: %1")
                                      .arg(serialPort->errorString()));
        return;
    }

    qDebug() << "成功发送控制指令:" << jsonData;
    ui->textEditSerialData->append(QString("[%1] 发送控制指令: %2")
                                  .arg(QDateTime::currentDateTime().toString("HH:mm:ss"))
                                  .arg(QString::fromUtf8(jsonData)));
}

